package com.xiyue.leaspring.util.interceptor;

import com.xiyue.leaspring.util.validate.ActionMIMEValidationUtil;
import com.xiyue.leaspring.util.validate.ActionValidationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ValidationInterceptor implements HandlerInterceptor {//定义拦截器

    private Logger logger = LoggerFactory.getLogger(ValidationInterceptor.class);

    @Autowired
    private MessageSource messageSource;//获取资源数据

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //this.logger.info("1.preHandle方法执行,"+handler.getClass());
        if (handler instanceof HandlerMethod) {//执行向下转型前应先判断是否是指定类的实例
            HandlerMethod handlerMethod = (HandlerMethod) handler;//强制类型转换
            String validationRuleKey = handlerMethod.getBeanType().getName()+"."+
                    handlerMethod.getMethod().getName();
            String validationRule = null;//保存要读取指定的资源key对应的验证规则
            try{//指定的key不存在,则不需要验证
                validationRule = this.messageSource.getMessage(validationRuleKey,null,null);
            }catch (Exception c){}
            if (validationRule!=null){//验证处理操作,则需要进行验证处理
                this.logger.info("【验证规则-{"+request.getRequestURI()+"}】"+validationRule);
                ActionValidationUtil avu = new ActionValidationUtil(validationRule,request
                ,this.messageSource);
                String errorPage = null;//错误页
                try {//获取但该案访问错误页
                    errorPage = this.messageSource.getMessage(validationRuleKey+
                            ".error.page",null,null);
                }catch (Exception e){//如果无指定路径，跳转到公共errorPage
                    errorPage = this.messageSource.getMessage("error.page",
                            null,null);
                }
                if(avu.getErrors().size()>0){//如果有错误信息
                    request.setAttribute("errors",avu.getErrors());//保存错误信息
                    //跳转到错误页
                    request.getRequestDispatcher(errorPage).forward(request,response);
                    return  false;//请求拦截
                }else {
                    if(request instanceof DefaultMultipartHttpServletRequest){//有上传
                        String mimeRule = null;
                        try {//获取文件规则,如果没有,则使用公共规则
                            mimeRule = this.messageSource
                                    .getMessage(validationRuleKey+".mine.rule",null,null);
                        }catch (Exception e){
                            mimeRule = this.messageSource
                                    .getMessage("mine.rule",null,null);
                        }
                        ActionMIMEValidationUtil amvu = new ActionMIMEValidationUtil(
                                mimeRule,request,this.messageSource);
                        if (amvu.getErrors().size()>0){//有错误
                            request.setAttribute("errors",amvu.getErrors());
                            request.getRequestDispatcher(errorPage).forward(request,response);
                        }
                    }
                }
            }
        }
        return true;//返回true,表示请求继承;返回flase,表示不执行后续的Action或拦截器
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        this.logger.info("2.postHandle方法执行,"+handler.getClass()+"、ModelAndView="+modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        this.logger.info("3.afterCompletion方法执行,"+handler.getClass());
    }
}
